package com.rede.didiok.admin.service.impl;

import java.util.*;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rede.didiok.admin.dao.SysParamsDao;
import com.rede.didiok.admin.entity.SysParamsEntity;
import com.rede.didiok.admin.service.SysParamsService;
import com.rede.didiok.common.constant.conf.MessageConf;
import com.rede.didiok.common.constant.conf.RedisConf;
import com.rede.didiok.common.constant.conf.SQLConf;
import com.rede.didiok.common.constant.conf.SysConf;
import com.rede.didiok.common.constant.global.Constants;
import com.rede.didiok.common.constant.global.ErrorCode;
import com.rede.didiok.common.dto.admin.SysParamsDto;
import com.rede.didiok.common.enums.StatusEnum;
import com.rede.didiok.common.exception.exceptionType.QueryException;
import com.rede.didiok.common.utils.*;

@Slf4j
@Service("sysParamsService")
public class SysParamsServiceImpl extends ServiceImpl<SysParamsDao, SysParamsEntity> implements SysParamsService {

    @Autowired
    RedisUtil redisUtil;

    /***************************** admin:start **************************/
    // region  didiok-admin

    @Override
    public IPage<SysParamsEntity> getPageList(SysParamsDto sysParamsDto) {
        QueryWrapper<SysParamsEntity> queryWrapper = new QueryWrapper<>();
        // 参数名称
        if (StringUtils.isNotEmpty(sysParamsDto.getParamsName())) {
            queryWrapper.like(SQLConf.PARAMS_NAME, sysParamsDto.getParamsName().trim());
        }
        // 参数键名
        if (StringUtils.isNotEmpty(sysParamsDto.getParamsKey())) {
            queryWrapper.like(SQLConf.PARAMS_KEY, sysParamsDto.getParamsKey().trim());
        }
        Page<SysParamsEntity> page = new Page<>();
        page.setCurrent(sysParamsDto.getCurrentPage());
        page.setSize(sysParamsDto.getPageSize());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.orderByDesc(SQLConf.SORT, SQLConf.CREATE_TIME);
        IPage<SysParamsEntity> pageList = this.page(page, queryWrapper);
        return pageList;
    }

    @Override
    public String addSysParams(SysParamsDto sysParamsDto) {
        // 判断添加的字典类型是否存在
        QueryWrapper<SysParamsEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.PARAMS_KEY, sysParamsDto.getParamsKey());
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.last(SysConf.LIMIT_ONE);
        SysParamsEntity temp = this.getOne(queryWrapper);
        if (temp != null) {
            return ResultUtil.errorWithMessage(MessageConf.ENTITY_EXIST);
        }
        SysParamsEntity sysParams = new SysParamsEntity();
        sysParams.setParamsName(sysParamsDto.getParamsName());
        sysParams.setParamsKey(sysParamsDto.getParamsKey());
        sysParams.setParamsValue(sysParamsDto.getParamsValue());
        sysParams.setParamsType(sysParamsDto.getParamsType());
        sysParams.setRemark(sysParamsDto.getRemark());
        sysParams.setSort(sysParamsDto.getSort());
        sysParams.insert();
        return ResultUtil.successWithMessage(MessageConf.INSERT_SUCCESS);
    }

    @Override
    public String editSysParams(SysParamsDto sysParamsDto) {
        SysParamsEntity sysParams = this.getById(sysParamsDto.getUid());
        // 判断编辑的参数键名是否存在
        if (!sysParamsDto.getParamsKey().equals(sysParams.getParamsKey())) {
            QueryWrapper<SysParamsEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(SQLConf.PARAMS_KEY, sysParamsDto.getParamsKey());
            queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
            queryWrapper.last(SysConf.LIMIT_ONE);
            SysParamsEntity temp = this.getOne(queryWrapper);
            if (temp != null) {
                return ResultUtil.errorWithMessage(MessageConf.ENTITY_EXIST);
            }
        }
        sysParams.setParamsName(sysParamsDto.getParamsName());
        sysParams.setParamsKey(sysParamsDto.getParamsKey());
        sysParams.setParamsValue(sysParamsDto.getParamsValue());
        sysParams.setParamsType(sysParamsDto.getParamsType());
        sysParams.setRemark(sysParamsDto.getRemark());
        sysParams.setSort(sysParamsDto.getSort());
        sysParams.setUpdateTime(new Date());
        sysParams.updateById();
        // 清空Redis中存在的配置
        redisUtil.delete(RedisConf.SYSTEM_PARAMS + RedisConf.SEGMENTATION + sysParamsDto.getParamsKey());
        return ResultUtil.successWithMessage(MessageConf.UPDATE_SUCCESS);
    }

    @Override
    public String deleteBatchSysParams(List<SysParamsDto> sysParamsVOList) {
        List<String> sysParamsUidList = new ArrayList<>();
        sysParamsVOList.forEach(item -> {
            sysParamsUidList.add(item.getUid());
        });
        if (sysParamsUidList.size() >= 0) {
            Collection<SysParamsEntity> sysParamsList = this.listByIds(sysParamsUidList);
            // 更新完成数据库后，还需要清空Redis中的缓存，因此需要存储键值
            List<String> redisKeys = new ArrayList<>();
            for (SysParamsEntity item : sysParamsList) {
                // 判断删除列表中是否含有系统内置参数
                if (item.getParamsType() == Constants.NUM_ONE) {
                    return ResultUtil.errorWithMessage("系统内置参数无法删除");
                }
                item.setStatus(StatusEnum.DISABLED);
                redisKeys.add(RedisConf.SYSTEM_PARAMS + RedisConf.SEGMENTATION + item.getParamsKey());
            }
            this.updateBatchById(sysParamsList);
            // 清空Redis中的配置
            redisUtil.delete(redisKeys);
            return ResultUtil.successWithMessage(MessageConf.DELETE_SUCCESS);
        } else {
            return ResultUtil.errorWithMessage(MessageConf.DELETE_FAIL);
        }
    }

    // endregion
    /***************************** admin:end **************************/



    /***************************** web:start **************************/
    // region didiok-web

    /**
     * 通过 参数键名 获取参数值
     *
     * @param paramsKey
     * @return
     */
    @Override
    public String getSysParamsValueByKey(String paramsKey) {
        // 判断Redis中是否包含该key的数据
        String redisKey = RedisConf.SYSTEM_PARAMS + RedisConf.SEGMENTATION + paramsKey;
        String paramsValue = redisUtil.get(redisKey);
        // 如果Redis中不存在，那么从数据库中获取
        if (StringUtils.isEmpty(paramsValue)) {
            SysParamsEntity sysParams = this.getSysParamsByKey(paramsKey);
            log.info("从库中获取：{}", sysParams);
            // 如果数据库也不存在，将抛出异常【需要到找到 doc/数据库脚本 更新数据库中的 t_sys_params表】
            if (sysParams == null || StringUtils.isEmpty(sysParams.getParamsValue())) {
                String errInfo = String.format("数据库a_params表，缺少配置文件：%s", paramsKey);
                log.error("[getSysParamsValueByKey] {}", errInfo);
                throw new QueryException(ErrorCode.PLEASE_CONFIGURE_SYSTEM_PARAMS, errInfo);
            }
            paramsValue = sysParams.getParamsValue();
            redisUtil.set(redisKey, paramsValue);
        }
        return paramsValue;
    }

    // endregion
    /***************************** web:end **************************/

    /**
     * 通过 参数键名 获取参数配置
     *
     * @param paramsKey
     * @return
     */
    @Override
    public SysParamsEntity getSysParamsByKey(String paramsKey) {
        QueryWrapper<SysParamsEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(SQLConf.PARAMS_KEY, paramsKey);
        queryWrapper.eq(SQLConf.STATUS, StatusEnum.ENABLE);
        queryWrapper.last(SysConf.LIMIT_ONE);
        SysParamsEntity sysParams = this.getOne(queryWrapper);
        return sysParams;
    }


}